package lumis.portal.device;

import java.io.File;

import javax.servlet.http.HttpServletRequest;

import lumis.portal.PortalContext;
import lumis.util.XmlUtil;
import lumis.util.log.ILogger;
import lumis.util.log.LoggerFactory;
import net.sourceforge.wurfl.core.CustomWURFLHolder;
import net.sourceforge.wurfl.core.WURFLHolder;
import net.sourceforge.wurfl.core.WURFLManager;
import net.sourceforge.wurfl.core.resource.XMLResource;

import org.w3c.dom.Node;

/**
 * Manages Device informations
 * 
 * @version $Revision: 13161 $ $Date: 2011-06-22 11:33:17 -0300 (Wed, 22 Jun 2011) $
 * @since 6.0.0
 */

public class WurflDeviceManager implements IDeviceManager
{

	/**
	 * Wurfl Holder
	 * @since 6.0.0
	 */
	private WURFLHolder wurflHolder;

	/**
	 * Logger used to register all errors.
	 * @since 6.0.0
	 */
	private ILogger logger = LoggerFactory.getLogger(WurflDeviceManager.class);
	
	/**
	 * Constructor that initialize the Wrufl holder based on deviceDetectionNode
	 * defined on lumisportalconfig.
	 * 
	 * @since 6.0.0
	 */
	public WurflDeviceManager()
	{
		// gets the deviceDetectionNode from PortalContext
		Node deviceDetectionNode = PortalContext.getDeviceDetectionNode();
		if (deviceDetectionNode == null)
		{
			// loads the default configuration
			wurflHolder = new CustomWURFLHolder(new File(PortalContext.getConfigPath("/device/wurfl.zip")));
		}
		else
		{
			Node[] fileNodes = null;
			try
			{
				fileNodes = XmlUtil.selectNodes("/deviceDetection/deviceDefinitions/file", deviceDetectionNode);
				// disable wurfl
				if (fileNodes.length <= 0)
				{
					wurflHolder = new CustomWURFLHolder(new XMLResource(getClass().getClassLoader().getResourceAsStream("lumis/portal/device/minimalWurfl.xml")));
				}
				else
				{
					// gets the root node file name
					File rootFile = new File(XmlUtil.getTextContent(fileNodes[0]));
					// gets the patch nodes file names
					File[] patchFiles = new File[fileNodes.length - 1];
					for (int x = 1; x < fileNodes.length; x++)
					{
						patchFiles[x] = new File(XmlUtil.getTextContent(fileNodes[x]));
					}
					wurflHolder = new CustomWURFLHolder(rootFile, patchFiles);
				}
			}
			catch (Exception e)
			{
				wurflHolder = new CustomWURFLHolder(new XMLResource(getClass().getClassLoader().getResourceAsStream("lumis/portal/device/minimalWurfl.xml")));
				logger.error("Erro occurred during process of read '/deviceDetection/deviceDefinitions/file'. The minimalWurfl.xml was assumed.");
			}

		}

	}
	
	/**
	 * Detects the device from the request and returns its capabilities.
	 * 
	 * @param request
	 *            the http request.
	 * @return the device informations.
	 */
	public IDevice discoverDevice(HttpServletRequest request)
	{
		WURFLManager wurflManager = wurflHolder.getWURFLManager();
		return new Device(wurflManager.getDeviceForRequest((HttpServletRequest) request));
	}

	public IDevice discoverDevice(String userAgent)
	{
		WURFLManager wurflManager = wurflHolder.getWURFLManager();
		return new Device(wurflManager.getDeviceForRequest(userAgent));
	}

}
